home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Precision Software Appli…tions Silver Collection 4
/
Precision Software Applications Silver Collection Volume 4 (1993).iso
/
new
/
bdc.arj
/
MGCOPY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-29
|
9KB
|
296 lines
/****************************************************************************
* *
MicroGenesis BULK Disk Copier
Copyright 1993 by MicroGenesis Software
Original version in May of '93
(email, in order of pref.)
CIS:76476,1701
AOL:JeffH66
DELPHI:HEATONJ
BIX: JHEATON
MicroGenesis Software
P.O. Box 25534
St. Louis, MO 63125
(314) 638-2506
(314) 638-1731 FAX
This source code may be distributed and modified freely. All I ask is that
this message(inside the two **** lines remain). It is okay to add
additional lines after here crediting whoever may modify this code. This
code may be used in any work: public,private,comercial or shareware. If
you do use it in some sort of product all I require is that you inform
me that you will be using it(by fax, email, us-mail, however).
Some of this source code is VERY dangerous! There are routines in here
designed to format/write directly to the disk surface. The exact same
routines are used to write to your hard disk drive. This code as is will
not write to your hard disk drive, but be CAREFUL when you modify
certian numbers or you may find yourself turning your hard drive into a
1.44meg floppy look-a-like!(I am not sure what would happen actually, by
some amazing quirk, I never inverted the numbers and killed my hard drive,
and loosing 200meg of info is not much of a fun "experiment".
SO as a result if you use this source code, and reformat your hard drive
or destroy it in some fassion I am not responsable. I provide no warranty
for this product of any sort. Use it at your own risk. Use it only on
A: and B: like it was designed for!
A really easy modification of this source code would allow you to create a
sort of a DISKCOPY for hard drives(even of different sizes). This source
code is not designed to do this, but it would make for an interesting mod.
If you need any advice on this EMAIL me.
Why did I write this program? Two reasons. The first version just to see
if I could still access drives direcly like the good old 8-bit computer
days. Second. This will form the backbone of a background disk duplication
program I am working on. I released the code because I couldnt find public
info on alot of this stuff.
Jeff Heaton, MicroGenesis Software
By the way, the order form is for our other products. You dont need to
pay for this one:)
* *
****************************************************************************/
#include <alloc.h>
#include <bios.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define FALSE 0
#define TRUE (!FALSE)
#define SECTORSIZE 512
// BIOS Int13 services we make use of
#define RESET 0
#define LAST 1
#define READ 2
#define WRITE 3
#define VERIFY 4
#define FORMAT 5
int density;// How many sectors are in a track
void msg(char (*s))
{
printf("%s\n", s);
_exit(1);
}
// Identify the error code with a real error message.
void Error(int (status))
{
switch (status)
{
// case 0x00:msg("Operation Successful"); break;
case 0x01:msg("Bad command"); break;
case 0x02:msg("Address mark not found"); break;
case 0x03:msg("Attempt to write on write-protected disk"); break;
case 0x04:msg("Sector not found"); break;
case 0x05:msg("Reset failed (hard disk)"); break;
// case 0x06:msg("Disk changed since last operation"); break;
case 0x07:msg("Drive parameter activity failed"); break;
case 0x08:msg("DMA overrun"); break;
case 0x09:msg("Attempt to DMA across 64K boundary"); break;
case 0x0A:msg("Bad sector detected"); break;
case 0x0B:msg("Bad track detected"); break;
case 0x0C:msg("Unsupported track"); break;
case 0x10:msg("Bad CRC/ECC on disk read"); break;
case 0x11:msg("CRC/ECC corrected data error"); break;
case 0x20:msg("Controller has failed"); break;
case 0x40:msg("Seek operation failed"); break;
case 0x80:msg("Attachment failed to respond"); break;
case 0xAA:msg("Drive not ready (hard disk only"); break;
case 0xBB:msg("Undefined error occurred (hard disk only)"); break;
case 0xCC:msg("Write fault occurred"); break;
case 0xE0:msg("Status error"); break;
case 0xFF:msg("Sense operation failed"); break;
default:return;
}
_exit(1);
}
// Identify what kind of diskette is installed in the specified drive.
// Return the number of sectors per track assumed as follows:
// 9 - 360 K and 720 K 5.25".
//15 - 1.2 M HD 5.25".
//18 - 1.44 M 3.5".
int nsects(int drive)
{
static int nsect[] = {18, 15, 9};
char *buffer;
int i, status;
// Read sector 1, head 0, track 0 to get the BIOS running.
buffer = (char *)malloc(SECTORSIZE);
biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
status = biosdisk(READ, drive, 0, 10, 1, 1, buffer);
if (status == 0x06) // Door signal change?
status = biosdisk(READ, drive, 0, 0, 1, 1, buffer);
for (i=0; i < sizeof(nsect)/sizeof(int); ++i)
{
biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
if (status == 0x06)
status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
if (status == 0x00) break;
}
if (i == sizeof(nsect)/sizeof(int))
{
msg("Can't figure out how many sectors/track for this diskette.");
}
free(buffer);
return(nsect[i]);
}
// Used to format a disk(a track at a time)
// This only formats the track to the point that we can write to it.
// If you would run format_track on each track of a disk the disk would
// NOT be usable. It would, however, be ready to be copied to.
//
// Using this on your hard drive(drive 2 or higher) would not really be
// a good idea! Infact the routine refuses to do so.
void format_track(int drive,int track)
{
struct FORMAT_ARRAY
{
char track,head,sector,bytes;
} array[30];
union REGS r;
struct SREGS s;
int i;
int head;
if( (drive>1) )// DONT EVEN THINK OF FORMATING THE HD!
return;
for(head=0;head<=1;head++)
{
for(i=0;i<density;i++)
{
array[i].track=track;
array[i].head=head;
array[i].sector=i+1;
array[i].bytes=2;
}
Error(biosdisk(FORMAT,drive,head,track,1,density,array));
}
}
void main(void)
{
char str[80];
char *buffer, *pbuf;
int drive, head, track, status, buflength, ns;
FILE *fp;
union REGS r;
long free;
int tracks;
puts("MicroGenesis BULK Disk Copier, Copyright 1993 by MicroGenesis Software\n");
if( (fp=fopen("fc.$$$","wb"))==NULL)
{
perror("FC.$$$");
exit(1);
}
printf("Enter source drive(A or B): ");
gets(str);
if(!*str)
exit(0);
drive = *str;
drive = (islower(drive) ? toupper(drive) : drive) - 'A';
printf("Please the source disk into ");
printf("drive %c: and press -ENTER- :", drive + 'A');
getch();
if(drive>1)
{
printf("Cant use this on hard drives!\r");
return;
}
// Determine number of sectors per track and allocate buffers.
density = nsects(drive);
buflength = density * SECTORSIZE;
buffer = (char *)malloc(buflength);
r.h.ah=0x1c;
r.h.dl=1;
int86(0x21,&r,&r);
tracks=(r.h.al*r.x.dx);
tracks=tracks/density;
tracks=tracks/2;
// Start writing data to diskette until there is no more data to write.
printf("\n\n\nPreparing to copy disk:\n");
printf("%i tracks, %i sectors per track\n",tracks,density);
head = track = 0;
for(track=0;track<=tracks;track++)
{
for(head=0;head<=1;head++)
{
Error(biosdisk(READ, drive, head, track,1, density, pbuf));
fwrite(pbuf,512,density,fp);
printf("Track: %i, Head: %i\r",track,head);
}
}
for(;;)
{
printf("\n\nPlease the destination disk into ");
printf("drive %c: and press -ENTER- :", drive + 'A');
getch();
putch('\n');
fclose(fp);
fp=fopen("FC.$$$","rb");
for(track=0;track<=tracks;track++)
{
format_track(drive,track);
for(head=0;head<=1;head++)
{
fread(pbuf,512,density,fp);
Error(biosdisk(WRITE, drive, head, track,1, density, pbuf));
printf("Track: %i, Sector: %i, Head: %i\r",track,0,head);
}
}
printf("\nDone.\n");
biosdisk(2, drive, 0, 0, 1, 1, buffer); /* Retract head */
fclose(fp);
printf("Make another copy of this disk(Y/N)");
if(toupper(getch())=='N')
break;
}
unlink("FC.$$$");
} /* end main */